﻿using AutoMapper;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using OpenAiProxy.API.Database;
using OpenAiProxy.API.Dtos;
using OpenAiProxy.API.Models;
using OpenAiProxy.API.ResourceParameters;

namespace OpenAiProxy.API.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class StatisticsController : ControllerBase
    {
        private readonly IDbContextFactory<MySqlDbContext> _dbContextFactory;
        private readonly IMapper _mapper;

        public StatisticsController(
            IDbContextFactory<MySqlDbContext> dbContextFactory,
            IMapper mapper
        )
        {
            _dbContextFactory = dbContextFactory;
            _mapper = mapper;
        }

        //注册PC
        [HttpPost("register/pc")]
        public async Task<IActionResult> RegisterPcAsync(
            [FromBody] WindowsInfoForCreationDto creationDto
        )
        {
            if (string.IsNullOrWhiteSpace(creationDto.CpuId))
            {
                return BadRequest("UserInfo requested.");
            }

            try
            {
                await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
                var queryable = from windowsInfo in dbContext.WindowsInfos
                    join accountInfo in dbContext.AccountInfos
                        on windowsInfo.Id equals accountInfo.DeviceId
                    where accountInfo.DeviceType == (int)DeviceType.Windows &&
                          windowsInfo.CpuId == creationDto.CpuId
                    select new
                    {
                        accountInfo
                    };
                var list = await queryable.ToListAsync();
                var accountId = list.FirstOrDefault()?.accountInfo.Id ?? $"{Guid.NewGuid()}".Replace("-", "");
                if (list.Any())
                {
                    return Ok(accountId);
                }

                //开启事务
                await using var transaction = await dbContext.Database.BeginTransactionAsync();

                //添加设备信息
                var windowsInfoModel = _mapper.Map<WindowsInfo>(creationDto);
                dbContext.WindowsInfos.Add(windowsInfoModel);
                await dbContext.SaveChangesAsync();

                //添加账户信息
                var accountInfoModel = new AccountInfo
                {
                    Id = accountId,
                    DeviceType = (byte)DeviceType.Windows,
                    DeviceId = windowsInfoModel.Id
                };
                dbContext.AccountInfos.Add(accountInfoModel);
                await dbContext.SaveChangesAsync();

                //提交事务
                // Commit transaction if all commands succeed, transaction will auto-rollback
                // when disposed if either commands fails
                await transaction.CommitAsync();

                return Ok(accountId);
            }
            catch (Exception e)
            {
                return Problem($"RegisterPc exception: {e.Message}.");
            }
        }

        //注册浏览器
        [HttpPost("register/browser")]
        public async Task<IActionResult> RegisterBrowserAsync(
            [FromBody] BrowserInfoForCreationDto creationDto
        )
        {
            if (string.IsNullOrWhiteSpace(creationDto.FingerCode))
            {
                return BadRequest("FingerCode requested.");
            }

            try
            {
                await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
                var queryable = from browserInfo in dbContext.BrowserInfos
                    join accountInfo in dbContext.AccountInfos
                        on browserInfo.Id equals accountInfo.DeviceId
                    where accountInfo.DeviceType == (int)DeviceType.Browser &&
                          browserInfo.FingerCode == creationDto.FingerCode
                    select new
                    {
                        accountInfo
                    };
                var list = await queryable.ToListAsync();
                var accountId = list.FirstOrDefault()?.accountInfo.Id ?? $"{Guid.NewGuid()}".Replace("-", "");
                if (list.Any())
                {
                    return Ok(accountId);
                }

                //开启事务
                await using var transaction = await dbContext.Database.BeginTransactionAsync();

                //添加设备信息
                var infoModel = _mapper.Map<BrowserInfo>(creationDto);
                dbContext.BrowserInfos.Add(infoModel);
                await dbContext.SaveChangesAsync();

                //添加账户信息
                var accountInfoModel = new AccountInfo
                {
                    Id = accountId,
                    DeviceType = (byte)DeviceType.Browser,
                    DeviceId = infoModel.Id
                };
                dbContext.AccountInfos.Add(accountInfoModel);
                await dbContext.SaveChangesAsync();

                //提交事务
                // Commit transaction if all commands succeed, transaction will auto-rollback
                // when disposed if either commands fails
                await transaction.CommitAsync();

                return Ok(accountId);
            }
            catch (Exception e)
            {
                return Problem($"RegisterBrowser exception: {e.Message}.");
            }
        }

        //留言接口
        [HttpPost("feedback/pc")]
        public async Task<IActionResult> FeedbackPcAsync(
            [FromBody] FeedbackResourceParameters resourceParameters
        )
        {
            if (string.IsNullOrWhiteSpace(resourceParameters.AccountId))
            {
                return BadRequest("UserInfo requested.");
            }

            try
            {
                await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
                var exist = await dbContext.AccountInfos.AnyAsync(t => t.Id == resourceParameters.AccountId);
                if (!exist)
                {
                    return BadRequest("Invalid user info.");
                }

                //添加设备信息
                var feedbackModel = new Feedback()
                {
                    Id = $"{Guid.NewGuid()}".Replace("-", ""),
                    AccountId = resourceParameters.AccountId,
                    Name = resourceParameters.Name ?? string.Empty,
                    Content = resourceParameters.Content ?? string.Empty,
                    CreateTime = DateTime.Now
                };
                dbContext.Feedbacks.Add(feedbackModel);
                await dbContext.SaveChangesAsync();

                return NoContent();
            }
            catch (Exception e)
            {
                return Problem($"FeedbackPc exception: {e.Message}.");
            }
        }
    }
}
